//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/* This code file contains attributes associated with workflow
 * parameters for use in scientific workflow projects.
 */

namespace Microsoft.Research.ScientificWorkflow
{
    /// <summary>
    /// A denotation that the data parameter represents output
    /// to the workflow activity.
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class OutputParamAttribute : Attribute
    {
        public OutputParamAttribute() { }
    }

    /// <summary>
    /// A denotation that the data parameter represents input
    /// to the workflow activity. Input parameters can either be
    /// marked as required or optional. Required input paramters
    /// must have a databinding set to an activity that sequences
    /// prior to the current activity in order to be valid.
    /// 
    /// The subclasses of InputParamAttribute provide alternate
    /// ways of writing the attribute. For instance:
    /// 
    /// [InputParam]
    /// [InputParam(false)]
    /// [OptionalInputParam]
    /// 
    /// are all equivalent. Similarly:
    /// 
    /// [InputParam(true)]
    /// [RequiredInputParam]
    /// 
    /// are also equivalent
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class InputParamAttribute : Attribute
    {
        private bool isRequired = false;

        /// <summary>
        /// Creates an optional input param
        /// </summary>
        public InputParamAttribute() : this(false) { }

        /// <summary>
        /// Allows the choice of required or optional when specifying
        /// an input param
        /// </summary>
        public InputParamAttribute(bool isRequired)
        {
            this.isRequired = isRequired;
        }

        /// <summary>
        /// When true, the activity is required to have a binding from
        /// an output parameter from another activity within the workflow
        /// </summary>
        public bool IsRequired
        {
            get { return isRequired; }
        }
    }

    /// <summary>
    /// Same as InputParam(true)
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class RequiredInputParamAttribute : InputParamAttribute
    {
        public RequiredInputParamAttribute() : base(true) { }
    }

    /// <summary>
    /// Same as InputParam(false)
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class OptionalInputParamAttribute : InputParamAttribute
    {
        public OptionalInputParamAttribute() : base(false) { }
    }

    /// <summary>
    /// A denotation that the data parameter represents input and ouput
    /// to the workflow activity. Input parameters can either be
    /// marked as required or optional. Required input paramters
    /// must have a databinding set to an activity that sequences
    /// prior to the current activity in order to be valid.
    /// 
    /// The subclasses of InoutParamAttribute provide alternate
    /// ways of writing the attribute. For instance:
    /// 
    /// [InOutParamAttribute]
    /// [InOutParamAttribute(false)]
    /// [OptionalInOutParamAttribute]
    /// 
    /// are all equivalent. Similarly:
    /// 
    /// [InOutParamAttribute(true)]
    /// [RequiredInOutParamAttribute]
    /// 
    /// are also equivalent
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class InOutParamAttribute : Attribute
    {
        private bool isRequired = false;

        /// <summary>
        /// Creates an optional input param
        /// </summary>
        public InOutParamAttribute() : this(false) { }

        /// <summary>
        /// Allows the choice of required or optional when specifying
        /// an input param
        /// </summary>
        public InOutParamAttribute(bool isRequired)
        {
            this.isRequired = isRequired;
        }

        /// <summary>
        /// When true, the activity is required to have a binding from
        /// an output parameter from another activity within the workflow
        /// </summary>
        public bool IsRequired
        {
            get { return isRequired; }
        }
    }

    /// <summary>
    /// Same as InOutParamAttribute(true)
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class RequiredInOutParamAttribute : InOutParamAttribute
    {
        public RequiredInOutParamAttribute() : base(true) { }
    }

    /// <summary>
    /// Same as InOutParamAttribute(false)
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class OptionalInOutParamAttribute : InOutParamAttribute
    {
        public OptionalInOutParamAttribute() : base(false) { }
    }

    /// <summary>
    /// The type of the parameter.
    /// </summary>
    public enum ParamType
    {
        /// <summary>
        /// Represents input parameter.
        /// </summary>
        InputParam = 0,

        /// <summary>
        /// Represents output parameter.
        /// </summary>
        OutputParam,

        /// <summary>
        /// Represents an in-out parameter.
        /// </summary>
        InOutParam
    }
}
